package mctx

import (
	"context"
	"jinrigaoping/pkg/constant"
	"jinrigaoping/pkg/xcode"
	"strconv"
)

func HaveOpUser(ctx context.Context) bool {
	return ctx.Value(constant.OpUserID) != nil
}

type CtxUserInfo struct {
	UserId     int64
	UserType   int32
	PlatformId int32
	MerchantId int64
}

func Check(ctx context.Context) (*CtxUserInfo, error) {
	opUserIDVal := ctx.Value(constant.OpUserID)
	opUserID, ok := opUserIDVal.(int64)
	if !ok {
		return &CtxUserInfo{}, xcode.NoOpUserId
	}
	if opUserID <= 0 {
		return &CtxUserInfo{}, xcode.NoOpUserId
	}
	opUserTypeArr, ok := ctx.Value(constant.OpUserType).([]string)
	if !ok {
		return &CtxUserInfo{}, xcode.NoOpUserType
	}
	if len(opUserTypeArr) == 0 {
		return &CtxUserInfo{}, xcode.NoOpUserType
	}
	userType, err := strconv.Atoi(opUserTypeArr[0])
	if err != nil {
		return &CtxUserInfo{}, xcode.UserTypeInvalid
	}
	if !(userType == constant.AdminUser || userType == constant.NormalUser || userType == constant.SuperAdminUser) {
		return &CtxUserInfo{}, xcode.UserTypeInvalid
	}

	// 商户id
	opMerchantIdVal := ctx.Value(constant.OpMerchantId)
	opMerchantId, ok := opMerchantIdVal.(int64)
	if !ok {
		return &CtxUserInfo{}, xcode.NoOpMerchantId
	}
	if opMerchantId <= 0 {
		return &CtxUserInfo{}, xcode.NoOpMerchantId
	}

	return &CtxUserInfo{
		UserId:     opUserID,
		UserType:   int32(userType),
		MerchantId: opMerchantId,
	}, nil
}

func CheckAdmin(ctx context.Context) (int64, error) {
	ctxUser, err := Check(ctx)
	if err != nil {
		return 0, err
	}
	if ctxUser.UserType != constant.AdminUser {
		return 0, xcode.NotAdmin
	}
	return ctxUser.UserId, nil
}

func CheckUser(ctx context.Context) (int64, error) {
	ctxUser, err := Check(ctx)
	if err != nil {
		return 0, err
	}
	if ctxUser.UserType != constant.NormalUser {
		return 0, xcode.NotUser
	}
	return ctxUser.UserId, nil
}

func CheckAdminOrUser(ctx context.Context) (int64, int32, error) {
	ctxUser, err := Check(ctx)
	if err != nil {
		return 0, 0, err
	}
	return ctxUser.UserId, ctxUser.UserType, nil
}

func GetOpUserID(ctx context.Context) int64 {
	userID, _ := ctx.Value(constant.OpUserID).(int64)
	return userID
}

func GetUserType(ctx context.Context) (int, error) {
	userTypeArr, _ := ctx.Value(constant.OpUserType).([]string)
	userType, err := strconv.Atoi(userTypeArr[0])
	if err != nil {
		return 0, xcode.UserTypeInvalid
	}
	return userType, nil
}

func WithOpUserID(ctx context.Context, opUserID string, userType int) context.Context {
	ctx = context.WithValue(ctx, constant.OpUserID, opUserID)
	ctx = context.WithValue(ctx, constant.OpUserType, []string{strconv.Itoa(userType)})

	return ctx
}
